/**
 * GTHttpRequest.m
 *
 * The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy of the License 
 * at http://www.mozilla.org/MPL/
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
 * either express or implied. See the License for the specific language governing rights and limitations 
 * under the License.
 *
 * The Original Code is gcast-toolbox4iphone.
 *
 * The Initial Developers of the Original Code is Giannandrea Castaldi.
 */
#import "GTHttpRequest.h"
#import "GTURLComposer.h"
#import "GTHttpParameter.h"

@interface GTHttpRequest ()
@property(nonatomic,retain, readwrite) NSURL *url;
@property(nonatomic,retain, readwrite) NSMutableDictionary *parameters;
@property(nonatomic,retain, readwrite) NSString *httpResult;
@property(nonatomic,retain, readwrite) NSDictionary *allHeaderFields;
@property(nonatomic,retain, readwrite) NSString *errorDescription;

- (GTHttpStatusCode)sendHttpMessage:(SEL)httpMessageComposer;
- (NSURLRequest*)composeHttpPostRequest;
- (NSURLRequest*)composeHttpGetRequest;
- (NSMutableData*)composePostData;
- (NSData *)formDataForParameter:(GTHttpParameter*)aParameter;
@end

@implementation GTHttpRequest
@synthesize url, parameters, httpResult, allHeaderFields, errorDescription, logEnabled;

+ (id)requestWithURL:(NSURL*)anUrl {
  return [[[GTHttpRequest alloc] initWithURL:anUrl] autorelease];
}

+ (id)requestWithUrl:(NSString*)anUrl {
  return [[[GTHttpRequest alloc] initWithUrl:anUrl] autorelease];
}

- (id)initWithURL:(NSURL*)anUrl {
  if ((self = [super init])) {
    self.url = anUrl;
    self.parameters = [NSMutableDictionary dictionary];
    self.logEnabled = FALSE;
  }
  return self;
}

- (id)initWithUrl:(NSString*)anUrl {
  return [self initWithURL:[NSURL URLWithString:anUrl]];
}

- (void)dealloc {
  [url release];
  [parameters release];
  [httpResult release];
  [allHeaderFields release];
  [errorDescription release];
  [super dealloc];
}

- (GTHttpStatusCode)sendHttpGet {
  return [self sendHttpMessage:@selector(composeHttpGetRequest)];
}

- (GTHttpStatusCode)sendHttpPost {
  return [self sendHttpMessage:@selector(composeHttpPostRequest)];
}

- (GTHttpStatusCode)sendHttpMessage:(SEL)httpMessageComposer {
  self.httpResult = nil;
  self.allHeaderFields = nil;
	self.errorDescription = nil;
	NSHTTPURLResponse *response = nil;
	NSError *error = nil;
	NSData *data = [NSURLConnection sendSynchronousRequest:[self performSelector:httpMessageComposer]
                                       returningResponse:&response
                                                   error:&error];
	if (error != nil) {
    self.errorDescription = [error localizedDescription];
    if (self.logEnabled) NSLog(@"GTHttpRequest.errorDescription: %@", self.errorDescription);
	}
	if (response != nil) {
		self.httpResult = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
    if (self.logEnabled) NSLog(@"GTHttpRequest.httpResult: %@", self.httpResult);
    self.allHeaderFields = [response allHeaderFields];
    if (self.logEnabled) NSLog(@"GTHttpRequest.allHeaderFields: %@", self.allHeaderFields);
	}
  if (self.logEnabled) NSLog(@"GTHttpRequest.statusCode: %d", [response statusCode]);
  return [response statusCode];
}

- (void)setParameter:(NSString*)aName withValue:(NSString*)aValue {
  [self.parameters setObject:[GTHttpParameter parameterWithName:aName value:aValue] forKey:aName];
}

- (NSString*)parameterValueForName:(NSString*)aName {
  GTHttpParameter *parameter = [self.parameters valueForKey:aName];
  return parameter.value;
}

- (NSURLRequest*)composeHttpPostRequest {
	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.url
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy 
                                                     timeoutInterval:60.0];
	[request setHTTPMethod:@"POST"];
	[request setHTTPBody:[self composePostData]];
  return request;
}

- (NSMutableData*) composePostData {
  NSMutableData *postData = [NSMutableData data];
  for (NSString *name in self.parameters) {
    [postData appendData:[self formDataForParameter:[self.parameters objectForKey:name]]];    
  }
  return postData;
}

- (NSURLRequest*)composeHttpGetRequest {
  GTURLComposer *urlComposer = [GTURLComposer composerWithStringBaseURL:[url absoluteString]];
  for (NSString *name in self.parameters) {
    GTHttpParameter *parameter = [self.parameters objectForKey:name];
    [urlComposer setParameter:parameter.name toValue:parameter.value];
  }
	NSMutableURLRequest *req=[NSMutableURLRequest requestWithURL:[urlComposer URL] 
                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy 
                                               timeoutInterval:60.0];
	[req setHTTPMethod: @"GET"];
  return req;
}

- (NSData *)formDataForParameter:(GTHttpParameter*)aParameter {
	NSString *escaped = [aParameter.name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
	NSString *form = [NSString stringWithFormat:@"%@=%@&", escaped, aParameter.value];
	return [form dataUsingEncoding: NSUTF8StringEncoding];
}

@end